package com.mercator.client.graph;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

import org.vaadin.gwtgraphics.client.DrawingArea;
import org.vaadin.gwtgraphics.client.Shape;

public class DCircleLayoutGraph<T extends Comparable<? super T>,N extends GNode<T,N,? extends Shape> & Drawable> extends
		DGraph<T, N, Graph<T,N>> {

	private double radius;
	private LinkedList<N> vertex_ordered_list;
	public static final MapName NAME = MapName.CIRCLE_MAP;
	
	public DCircleLayoutGraph(DrawingArea canvas) {
		super(canvas);
		this.canvas = canvas;
		this.container = new SimpleGraph<T,N>();
	}
	
	@Override
	public MapName getName() {
		return NAME;
	}

	public void move() {
		animate();
	}

	/**
	 * A {@code Layout} implementation that positions vertices equally spaced on
	 * a regular circle.
	 * 
	 * @author Masanori Harada
	 */

	/**
	 * Returns the radius of the circle.
	 */
	public double getRadius() {
		return radius;
	}

	/**
	 * Sets the radius of the circle. Must be called before {@code initialize()}
	 * is called.
	 */
	public void setRadius(double radius) {
		this.radius = radius;
	}

	/**
	 * Sets the order of the vertices in the layout according to the ordering
	 * specified by {@code comparator}.
	 */
	public void setVertexOrder(Comparator<N> comparator) {
		if (vertex_ordered_list == null)
			vertex_ordered_list = new LinkedList<N>(container.values());
		Collections.sort(vertex_ordered_list, comparator);
	}

	/**
	 * Sets the order of the vertices in the layout according to the ordering of
	 * {@code vertex_list}.
	 */
	public void setVertexOrder(LinkedList<N> vertex_list) {
		Collections.sort(vertex_list);
		this.vertex_ordered_list = vertex_list;
	}

	public String toString() {
		return super.toString();
	}

	@Override
	public void animate() {
		if (vertex_ordered_list == null)
			setVertexOrder(new LinkedList<N>(container.values()));

		double height = canvas.getHeight();
		double width = canvas.getWidth();
		// System.err.println("Height: " + height + "Width: " + width);
		if (radius <= 0) {
			radius = 0.45 * (height < width ? height : width);
		}

		// getPivot().moveTo(width/2, height/2);
		// getPivot().animate(canvas);
		int i = 1;
		
		for (N v : container.getCol()) {
			double angle = (2 * Math.PI * i) / (container.order());
			double x = Math.cos(angle) * radius + width / 2;
			double y = Math.sin(angle) * radius + height / 2;
			i++;
			v.moveTo(x, y);
			v.animate();
			
		}
		

	}

	public void removeAll() {

		for (N g : this) {
			canvas.remove(g.reps);

		}
		super.removeAll();
	}

	@Override
	public void moveTo(double x, double y) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void addAll(Collection<T> col){
		for (T t : col)
			add(t);
	}
}
